package com.msite.config

import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression
import org.springframework.boot.context.properties.ConfigurationProperties
import org.springframework.boot.context.properties.EnableConfigurationProperties
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.data.redis.connection.RedisNode
import org.springframework.data.redis.connection.RedisSentinelConfiguration
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory
import org.springframework.data.redis.core.RedisOperations
import org.springframework.data.redis.core.RedisTemplate
import org.springframework.util.Assert
import org.springframework.util.StringUtils
import redis.clients.jedis.JedisPoolConfig

/**
 * Created by tpeng on 2015/12/3.
 */
@Configuration
@EnableConfigurationProperties
@ConfigurationProperties(prefix = "redis")
@ConditionalOnExpression("false")//('${redis.enable:false}')
class RedisConfig {

    private int database = 0;
    private String host;
    private String password;
    private int port;

    private int maxIdle = 8;
    private int minIdle = 0;
    private int maxActive = 8;
    private int maxWait = -1;

    private String sentinelMaster;
    private String sentinelNodes;

    @Bean
    public JedisConnectionFactory redisConnectionFactory() throws UnknownHostException {
        RedisSentinelConfiguration sentinelConfig = null;
        if (this.sentinelMaster) {
            sentinelConfig = new RedisSentinelConfiguration(
                    master: this.sentinelMaster,
                    sentinels: createSentinels(this.sentinelNodes)
            )
        }

        def config = new JedisPoolConfig(
                maxTotal: this.maxActive,
                maxIdle: this.maxIdle,
                minIdle: this.minIdle,
                maxWaitMillis: this.maxWait);

        def factory = new JedisConnectionFactory(
                sentinelConfig: sentinelConfig,
                poolConfig: config,
                hostName: this.host,
                port: this.port,
                database: this.database
        )
        if (this.password) {
            factory.setPassword(this.password);
        }
        factory
    }

    @Bean
    public RedisOperations<Object, Object> redisTemplate() throws UnknownHostException {
        new RedisTemplate<Object, Object>(connectionFactory: redisConnectionFactory())
    }

    private List<RedisNode> createSentinels(String sentinelNodes) {
        List<RedisNode> sentinels = new ArrayList<RedisNode>();
        for (String node : StringUtils.commaDelimitedListToStringArray(sentinelNodes)) {
            try {
                String[] parts = StringUtils.split(node, ":");
                Assert.state(parts.length == 2, "Must be defined as 'host:port'");
                sentinels.add(new RedisNode(parts[0], Integer.valueOf(parts[1])));
            }
            catch (RuntimeException ex) {
                throw new IllegalStateException("Invalid redis sentinel "
                        + "property '" + node + "'", ex);
            }
        }
        sentinels
    }

}
